package tinyinventor;

import renderable.RenderableBlock;
import workspace.WorkspaceEvent;
import workspace.WorkspaceListener;
import codeblocks.Block;
import codeblocks.BlockConnector;
import codeblocks.BlockLink;
import codeblocks.BlockStub;
import codeblocks.LinkRule;

public class ParamAssignmentRule implements LinkRule, WorkspaceListener {

    public boolean canLink(Block block1, Block block2, BlockConnector socket1, BlockConnector socket2) {
    	
    	switch (socket1.getPositionType()) {
        case BOTTOM:
        case TOP:
            return false; // we're only checking params, so ignore top and bottom connectors
        }
        
        //System.out.println("block1 decl? " + block1.isProcedureDeclBlock() + ", block2 decl? " + block2.isProcedureDeclBlock());
        //System.out.println("block1 param? " + block1.isProcedureParamBlock() + ", block2 param? " + block2.isProcedureParamBlock());
        
    	return block1.isProcedureDeclBlock() && block2.isProcedureParamBlock() ||
    		   block2.isProcedureDeclBlock() && block1.isProcedureParamBlock();
    	
    }

    public boolean isMandatory() {
        return false;
    }

	@Override
	public void workspaceEventOccurred(WorkspaceEvent event) {
		if(event.getEventType()==WorkspaceEvent.BLOCKS_CONNECTED) {
			BlockLink link = event.getSourceLink();
			
			if(Block.getBlock(link.getPlugBlockID()).isProcedureParamBlock()) {
				link.getPlug().setKind(link.getSocket().getKind());
				redrawBlockAndStubs(link.getPlug(), link.getSocket().getKind());
			}
			
			if(Block.getBlock(link.getSocketBlockID()).isProcedureParamBlock()) {
				link.getSocket().setKind(link.getPlug().getKind());
				redrawBlockAndStubs(link.getSocket(), link.getPlug().getKind());
			}			
		} else if(event.getEventType()==WorkspaceEvent.BLOCKS_DISCONNECTED) {
			BlockLink link = event.getSourceLink();
			
			System.out.println("disconnected");
			
			if(Block.getBlock(link.getPlugBlockID()).isProcedureDeclBlock()) {
				System.out.println("found decl");
				if(!link.getPlug().getKind().equals("proc-param")) {
					System.out.println("with no param");
					redrawBlockAndStubs(link.getSocket(), "proc-param");
				}
				else {
					System.out.println("but has param");
				}
			}
			
			if(Block.getBlock(link.getSocketBlockID()).isProcedureDeclBlock()) {
				System.out.println("found decl");
				if(!link.getSocket().getKind().equals("proc-param")) {
					System.out.println("with no param");
					link.getPlug().setKind("proc-param");
					redrawBlockAndStubs(link.getPlug(), "proc-param");
				} else {
					System.out.println("but has param");
				}
			}
			
		}
	}
	
	private void redrawBlockAndStubs(BlockConnector parentConnector, String kind) {
		parentConnector.setKind(kind);
		RenderableBlock.getRenderableBlock(parentConnector.getBlockID()).repaintBlock();
		for(Long stubID : BlockStub.getStubsOfParent(parentConnector.getBlockID())) {
			BlockConnector plug = Block.getBlock(stubID).getPlug();
			if(plug!=null) {
				plug.setKind(kind);
			}
			for(BlockConnector c : Block.getBlock(stubID).getSockets()) {
				c.setKind(kind);
			}
			//RenderableBlock.getRenderableBlock(stubID).redrawFromTop();
			RenderableBlock.getRenderableBlock(stubID).repaintBlock();
			
		}
	}	
}
